package it.tukano.treditor.engine;

import it.tukano.treditor.engine.input.EngineInputListener;
import it.tukano.treditor.engine.scene.DirectionalLightElement;
import it.tukano.treditor.engine.scene.MeshElement;
import it.tukano.treditor.engine.scene.ModelElement;
import it.tukano.treditor.engine.scene.NodeElement;
import it.tukano.treditor.engine.scene.SceneElement;
import it.tukano.treditor.engine.scene.SceneView;
import java.net.URL;
import javax.swing.JComponent;

/**
 * Engine abstraction
 * @author pgi
 */
public interface Engine3D {
    
    /**
     * Returns the file extensions of the model formats supported by this engine
     * @return an array of strings denoting file name extensions (with or without
     * the leading dot, like "obj" "3ds" ".dae")
     */
    public String[] getSupportedModelFormatExtensions();

    /**
     * Add a light to the scene
     * @param lightElement the light to add
     * @param parentElement the node where to add the light
     */
    public void addDirectionalLightToNode(DirectionalLightElement lightElement, NodeElement parentElement);

    /**
     * Sets the current view on the 3d scene
     * @param view the view data to use
     */
    public void setView(SceneView view);

    /**
     * The color or direction of a directional light element has been changed
     * @param updatedLight the light that has been updated
     */
    public void updateDirectionalLight(DirectionalLightElement updatedLight);

    /**
     * An element has been removed from a node. Update the rendered scene.
     * @param element the element that has been removed
     * @param node the node from where the element has been removed.
     */
    public void removeElementFromNode(SceneElement element, NodeElement node);
  
    /**
     * Initializes the engine. Called in the edt thread
     */
    public void edtInitialize();

    /**
     * Returns the engine's display. Called in the edt
     * @return the engine's display
     */
    public JComponent edtGetDisplayComponent();

    /**
     * Disposes the engine. Called in the edt
     */
    public void edtDispose();
    
    /**
     * Set the root of the scene. The root is where the elements of the universe
     * are added
     * @param newRoot the new root element
     */
    public void setSceneRoot(NodeElement newRoot);

    /**
     * Set the temp root of the scene. The temp root is where the decoration
     * elements are added (selection boxes, arrows, grids, tooltips and alike)
     * @param newTempRoot the new temporary elements' root
     */
    public void setTempRoot(NodeElement newTempRoot);
    
    /**
     * Checks if this engine supports the format of the model at the given address
     * @param modelAddress the address of the model to check
     * @return true if the engine can load the given model, false otherwise
     */
    public boolean isModelFormatSupported(URL modelAddress);
    
    /**
     * Add an element to the scene
     * @param model the new element
     * @param parent the parent of the element
     */
    public void addModelToNode(ModelElement model, NodeElement parent);
    
    /**
     * Add a mesh to the scene
     * @param model the mesh to add
     * @param parent the parent of the mesh
     */
    public void addMeshToNode(MeshElement model, NodeElement parent);
    
    /**
     * Add an empty node to the scene
     * @param emptyChild the empty node to add
     * @param parent the parent
     */
    public void addEmptyNodeToNode(NodeElement emptyChild, NodeElement parent);
    
    /**
     * Updates the transform of a model
     * @param updatedModel the model whose transform has been changed
     */
    public void updateModelTransform(ModelElement updatedModel);
    
    /**
     * Sets the unique engine input listener used to be notified of interaction events
     * @param listener the listener to add
     */
    public void setEngineInputListener(EngineInputListener listener);
    
    /**
     * Returns the set of methods that can be used to get values from the engine.
     * @return this engine's query interface
     */
    public EngineQueryInterface getQueryInterface();
}
